package logger

import (
	"fmt"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"gopkg.in/natefinch/lumberjack.v2"
	"os"
	"path/filepath"
)

var Logger *zap.Logger

// InitLogger 初始化日志系统
func InitLogger(logPath string, maxSize int) error {
	// 确保日志目录存在
	logDir := filepath.Dir(logPath)
	if err := os.MkdirAll(logDir, 0755); err != nil {
		return fmt.Errorf("创建日志目录失败: %v", err)
	}

	// 日志轮转配置
	hook := &lumberjack.Logger{
		Filename:   logPath,
		MaxSize:    maxSize, // MB
		MaxBackups: 5,
		MaxAge:     30,   // 天
		Compress:   true, // 压缩旧日志
	}

	encoderConfig := zapcore.EncoderConfig{
		TimeKey:        "time",
		LevelKey:       "level",
		NameKey:        "logger",
		CallerKey:      "caller",
		MessageKey:     "msg",
		StacktraceKey:  "stacktrace",
		LineEnding:     zapcore.DefaultLineEnding,
		EncodeLevel:    zapcore.LowercaseLevelEncoder,
		EncodeTime:     zapcore.RFC3339TimeEncoder,
		EncodeDuration: zapcore.SecondsDurationEncoder,
		EncodeCaller:   zapcore.ShortCallerEncoder,
	}

	// 同时输出到文件和控制台
	fileWriter := zapcore.AddSync(hook)
	consoleWriter := zapcore.AddSync(os.Stdout)

	core := zapcore.NewTee(
		zapcore.NewCore(
			zapcore.NewJSONEncoder(encoderConfig),
			fileWriter,
			zapcore.InfoLevel,
		),
		zapcore.NewCore(
			zapcore.NewConsoleEncoder(encoderConfig),
			consoleWriter,
			zapcore.InfoLevel,
		),
	)

	Logger = zap.New(core, zap.AddCaller(), zap.AddStacktrace(zapcore.ErrorLevel))
	return nil
}

// Info 记录普通信息
func Info(msg string, fields ...zap.Field) {
	Logger.Info(msg, fields...)
}

// Error 记录错误信息
func Error(msg string, err error, fields ...zap.Field) {
	if err != nil {
		fields = append(fields, zap.Error(err))
	}
	Logger.Error(msg, fields...)
}

// Fatal 记录致命错误并退出
func Fatal(msg string, err error, fields ...zap.Field) {
	if err != nil {
		fields = append(fields, zap.Error(err))
	}
	Logger.Fatal(msg, fields...)
}

// WithFields 创建带有固定字段的 Logger
func WithFields(fields ...zap.Field) *zap.Logger {
	return Logger.With(fields...)
}

// Println 兼容旧的日志接口
func Println(args ...interface{}) {
	if Logger == nil {
		fmt.Println(args...)
		return
	}
	msg := fmt.Sprint(args...)
	Logger.Info(msg)
}

// Printf 兼容旧的日志接口
func Printf(format string, args ...interface{}) {
	if Logger == nil {
		fmt.Printf(format, args...)
		return
	}
	msg := fmt.Sprintf(format, args...)
	Logger.Info(msg)
}
